//-----------------------------------------------------------------------
// <copyright file="DeleteFiles.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY 
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
// </copyright>
// <author>Chris Williams</author>
// <email></email>
// <date>2004-03-23</date>
// <summary>Deletes the specified files that match the mask in the folder specified.</summary>
//-----------------------------------------------------------------------

namespace Microsoft.Sdc.Tasks.File
{
    using System;
    using System.Xml;
    using System.Globalization;
    using System.IO;
    using Microsoft.Build.Framework;
    using System.Collections;

    /// <summary>
    /// Deletes files nad if neccessary can remove readonly files.
    /// </summary>
    /// <remarks>
    /// <code><![CDATA[<File.DeleteFiles Files="files" TreatErrorsAsWarnings="treatErrorsAsWarnings" Force="force" />]]></code>
    /// <para>where:</para>
    /// <para><i>files (Required)</i></para>
    /// <para>The file(s) to be deleted.</para>
    /// <para><i>treatErrorsAsWarnings</i></para>
    /// <para>True to treat any errors whilst deleting as warnings.</para>
    /// <para><i>force</i></para>
    /// <para>True to force the deletion of the file(s) if they are readonly.</para>
    /// </remarks>
    /// <example>
    /// <code><![CDATA[
    /// <Project>
    ///     <Target Name="Test" >
    ///         <File.DeleteFiles
    ///             Files="C:\CopiedAssemblies\bob.dll"
    ///             TreatErrorsAsWarnings="false"
    ///             Force="true">
    ///             <Output TaskParameter="DeletedFiles" ItemName="FilesThatWereDeleted" />
    ///         </File.DeleteFiles>
    ///         <Message Text="The files that were removed were @(FilesThatWereDeleted)" />
    ///     </Target>
    /// </Project>
    /// ]]></code>    
    /// </example>
    public class DeleteFiles : TaskBase
    {
        private ITaskItem[] files;
        private ITaskItem[] deletedFiles;
        private bool force;
        private bool treatErrorsAsWarnings;

        /// <summary>
        /// If TRUE any errors will be logged as warnings
        /// </summary>
        public bool TreatErrorsAsWarnings
        {
            get { return treatErrorsAsWarnings; }
            set { treatErrorsAsWarnings = value; }
        }

        /// <summary>
        /// The files to be deleted
        /// </summary>
        /// <value>An ITaskItem array of files</value>
        [Required]
        public ITaskItem[] Files
        {
            get { return this.files; }
            set { this.files = value; }
        }

        /// <summary>
        /// The files that were successfully deleted
        /// </summary>
        [Output]
        public ITaskItem[] DeletedFiles
        {
            get { return this.deletedFiles; }
            set { this.deletedFiles = value; }
        } 

        /// <summary>
        /// If set to true, it will set the attributes of all files such that they can be deleted.
        /// </summary>
        /// <value>True to force the deletion of files, otherwise false.</value>
        public bool Force
        {
            get { return this.force; }
            set { this.force = value; }
        }        

        /// <summary>
        /// Performs the action of this task.
        /// </summary>
        protected override void InternalExecute()
        {

            ArrayList deletedFilesList = new ArrayList();
            foreach (ITaskItem file in this.Files)
            {
                try
                {
                    if (File.Exists(file.ItemSpec))
                    {
                        base.Log.LogMessageFromResources(MessageImportance.Normal, "File.Delete.DeletingFile", file.ItemSpec);
                        if (this.Force)
                        {
                            File.SetAttributes(file.ItemSpec, FileAttributes.Normal);
                        }
                        File.Delete(file.ItemSpec);
                    }
                    else
                    {
                        base.Log.LogMessageFromResources(MessageImportance.Low, "File.Delete.SkippingNonexistentFile", file.ItemSpec);
                    }
                    deletedFilesList.Add(file);
                }
                catch (Exception ex)
                {
                    Utilities.RethrowUnlessFileIO(ex);
                    this.LogError(file, ex);
                }
/* GK no such thing as non compliant exception in RTM CLS
                catch
                {
                    throw;
                }
*/ 
            }
            this.DeletedFiles = (ITaskItem[])deletedFilesList.ToArray(typeof(ITaskItem));
        }

        private void LogError(ITaskItem file, Exception e)
        {
            if (this.TreatErrorsAsWarnings)
            {
                base.Log.LogWarningWithCodeFromResources("File.Delete.Error", file.ItemSpec, e.Message);
            }
            else
            {
                base.Log.LogErrorWithCodeFromResources("File.Delete.Error", file.ItemSpec, e.Message) ;
            }
        }
    }
}